package com.dxy.chatserver.service;

import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.model.*;
import com.dxy.chatserver.db.entity.OnlineMessageBuild;
import com.dxy.chatserver.db.entity.AcceptLineMsgResponse;
import com.dxy.chatserver.config.TSConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class TsService {

    public static final SyncClient client = new SyncClient(TSConfig.endPoint, TSConfig.accessId, TSConfig.accessKey, TSConfig.instanceName);

    public static void createTable(){
        TableMeta tableMeta = new TableMeta(OnlineMessageBuild.DB_NAME);
        //第一列为会话id。
        tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(OnlineMessageBuild.sessionId, PrimaryKeyType.STRING));
        //第二列为自定义消息。
        tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(OnlineMessageBuild.msgId, PrimaryKeyType.STRING));
        //第三列为消息ID，自动自增列，类型为INTEGER，属性为PKO_AUTO_INCREMENT。
        tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(OnlineMessageBuild.createTime, PrimaryKeyType.STRING));
        int timeToLive = -1;  //永不过期，也可以设置数据有效期，过期了会自动删除。
        int maxVersions = 1;  //只保存一个版本，目前支持多版本。
        TableOptions tableOptions = new TableOptions(timeToLive, maxVersions);

        CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions);
        client.createTable(request);
    }

    private static void deleteTable() {
        DeleteTableRequest request = new DeleteTableRequest(OnlineMessageBuild.DB_NAME);
        client.deleteTable(request);
    }

//    public static void main(String[] args) {
//        deleteTable();
//        createTable();
//    }

    /**
     * 保存数据 --单行
     * @param response
     */
    public static void putRow(AcceptLineMsgResponse response) {
        //构造主键。
        PrimaryKey primaryKey = OnlineMessageBuild.createPrimaryKeyBuilder(response);
        //设置数据表名称。
        RowPutChange rowPutChange = new RowPutChange(OnlineMessageBuild.DB_NAME, primaryKey);

        //加入一些属性列。
        OnlineMessageBuild.createRowPutChange(rowPutChange,response);

        client.putRow(new PutRowRequest(rowPutChange));
    }

    /**
     * 批量写入
     * @param msgResponses
     */
    public static void batchWriteRow(List<AcceptLineMsgResponse> msgResponses) {
        if(msgResponses.isEmpty() || msgResponses.size()>200){
            log.info("数据不能进行写入");
            return;
        }
        BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();
        msgResponses.forEach(commit->{
            PrimaryKey primaryKey = OnlineMessageBuild.createPrimaryKeyBuilder(commit);
            RowPutChange rowPutChange1 = new RowPutChange(OnlineMessageBuild.DB_NAME, primaryKey);
            batchWriteRowRequest.addRowChange(OnlineMessageBuild.createRowPutChange(rowPutChange1, commit));
        });

        BatchWriteRowResponse response = client.batchWriteRow(batchWriteRowRequest);
        log.info("是否全部成功：" + response.isAllSucceed() +"写入数量:"+response.getSucceedRows().size());
        if (!response.isAllSucceed()) {
            for (BatchWriteRowResponse.RowResult rowResult : response.getFailedRows()) {
                log.error("失败的行：" + batchWriteRowRequest.getRowChange(rowResult.getTableName(), rowResult.getIndex()).getPrimaryKey());
                log.error("失败原因：" + rowResult.getError());
            }
        }
    }

    /**
     * 单行
     */
    public static Row getRow(String sessionId,String msgId,String createTime) {
        //构造主键。
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn(OnlineMessageBuild.sessionId,PrimaryKeyValue.fromString(sessionId));
        primaryKeyBuilder.addPrimaryKeyColumn(OnlineMessageBuild.msgId, PrimaryKeyValue.fromString(msgId));
        primaryKeyBuilder.addPrimaryKeyColumn(OnlineMessageBuild.createTime, PrimaryKeyValue.fromString(createTime));
        PrimaryKey primaryKey = primaryKeyBuilder.build();

        //读取一行数据，设置数据表名称。
        SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(OnlineMessageBuild.DB_NAME, primaryKey);
        //设置读取最新版本。
        criteria.setMaxVersions(1);
        GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
        return getRowResponse.getRow();
    }

    public static void getRange(String sessionId) {
        getRange(sessionId,null,null,null,null);
    }

    public static void getRange(String sessionId,String msgIdStart,String createTimeStart,String msgIdEnd,String createTimeEnd) {
        //查询的数据库指定
        RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(OnlineMessageBuild.DB_NAME);

        //开始主键
        rangeRowQueryCriteria.setInclusiveStartPrimaryKey(OnlineMessageBuild.createPrimaryKeyRangeMin(sessionId,msgIdStart,createTimeStart));

        //设置结束主键。
        rangeRowQueryCriteria.setExclusiveEndPrimaryKey(OnlineMessageBuild.createPrimaryKeyRangeMax(sessionId,msgIdEnd,createTimeEnd));

        rangeRowQueryCriteria.setMaxVersions(1);

        log.info("GetRange的结果为：");
        Integer allSize = 0;
        while (true) {
            GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
            for (Row row : getRangeResponse.getRows()) {
                allSize++;
                log.info("第{}行，输出:{}",allSize,row.getPrimaryKey());
            }
            //如果NextStartPrimaryKey不为null，则继续读取。
            if (getRangeResponse.getNextStartPrimaryKey() != null) {
                rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
            } else {
                break;
            }
        }
        log.info("当前总数据:{}",allSize);
    }

}
